#include "./ctrl.h"
#include "../xlib/gpio.h"

namespace driver {

Ctrl ctrl;

using namespace stm32f1;

namespace ctrl_impl {

using namespace gpio;

using COOKING_ROOM_LED = Cfg<PC<6>, Mode::OUT_50MHz_PP>;
using COOKING_ROOM_FAN = Cfg<PC<7>, Mode::OUT_50MHz_PP>;
using RADIATE_FAN = Cfg<PC<8>, Mode::OUT_50MHz_PP>;
using DRAIN_PUMP = Cfg<PC<9>, Mode::OUT_50MHz_PP>;

using V1 = Cfg<PB<8>, Mode::OUT_50MHz_PP>;
using V2 = Cfg<PB<9>, Mode::OUT_50MHz_PP>;
using V3 = Cfg<PC<13>, Mode::OUT_50MHz_PP>;
using V4 = Cfg<PC<14>, Mode::OUT_50MHz_PP>;
using V5 = Cfg<PB<7>, Mode::OUT_50MHz_PP>;
using V6 = Cfg<PB<6>, Mode::OUT_50MHz_PP>;
using V7 = Cfg<PB<5>, Mode::OUT_50MHz_PP>;
using V8 = Cfg<PB<4>, Mode::OUT_50MHz_PP>;

using HEAT_WATER = Cfg<PB<3>, Mode::OUT_50MHz_PP>;
using HEAT_STEAM = Cfg<PD<2>, Mode::OUT_50MHz_PP>;
using WATER_PUMP = Cfg<PC<12>, Mode::OUT_50MHz_PP>;

} // namespace ctrl_impl

using namespace ctrl_impl;

void Ctrl::init() {
    rcc::enable<COOKING_ROOM_LED, COOKING_ROOM_FAN, RADIATE_FAN, DRAIN_PUMP, V1,
                V2, V3, V4, V5, V6, V7, V8, HEAT_WATER, HEAT_STEAM,
                WATER_PUMP>();
    gpio::config<COOKING_ROOM_LED, COOKING_ROOM_FAN, RADIATE_FAN, DRAIN_PUMP,
                 V1, V2, V3, V4, V5, V6, V7, V8, HEAT_WATER, HEAT_STEAM,
                 WATER_PUMP>();
    gpio::clr<COOKING_ROOM_LED, COOKING_ROOM_FAN, RADIATE_FAN, DRAIN_PUMP, V1,
              V2, V3, V4, V5, V6, V7, V8, HEAT_WATER, HEAT_STEAM, WATER_PUMP>();
    m_mutex.init();
}

void Ctrl::open(uint8_t id) {
    AUTO_LOCK(m_mutex);
    switch (id) {

#define XX(ID, NAME, DESCR)                                                    \
    case ID:                                                                   \
        NAME::set();                                                           \
        break;
        CTRL_PARTS(XX)
#undef XX
    default:
        return;
    }
    m_flags |= 0x01 << id;
}

void Ctrl::close(uint8_t id) {
    AUTO_LOCK(m_mutex);
    switch (id) {
#define XX(ID, NAME, DESCR)                                                    \
    case ID:                                                                   \
        NAME::clr();                                                           \
        break;

        CTRL_PARTS(XX)
#undef XX
    default:
        return;
    }
    m_flags &= ~(0x01 << id);
}

} // namespace driver
